home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / Audio.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-20  |  50.4 KB  |  1,920 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Copyright (C) 1998-2001 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include "VirtualDub.h"
  19.  
  20. #include <string.h>
  21. #include <crtdbg.h>
  22.  
  23. #include <windows.h>
  24.  
  25. #include "gui.h"
  26. #include "crash.h"
  27.  
  28. #include "Error.h"
  29. #include "AudioSource.h"
  30.  
  31. #include "audio.h"
  32.  
  33. AudioFormatConverter AudioPickConverter(WAVEFORMATEX *src, BOOL to_16bit, BOOL to_stereo);
  34.  
  35. //////////////// no change converters /////////////////////////////////////
  36.  
  37. static void convert_audio_nochange8(void *dest, void *src, long count) {
  38.     memcpy(dest, src, count);
  39. }
  40.  
  41. static void convert_audio_nochange16(void *dest, void *src, long count) {
  42.     memcpy(dest, src, count*2);
  43. }
  44.  
  45. static void convert_audio_nochange32(void *dest, void *src, long count) {
  46.     memcpy(dest, src, count*4);
  47. }
  48.  
  49. //////////////// regular converters /////////////////////////////////////
  50.  
  51. static void convert_audio_mono8_to_mono16(void *dest, void *src, long count) {
  52.     unsigned char *s = (unsigned char *)src;
  53.     signed short *d = (signed short *)dest;
  54.  
  55.     do {
  56.         *d++ = (signed short)((unsigned long)(*s++-0x80)<<8);
  57.     } while(--count);
  58. }
  59.  
  60. static void convert_audio_mono8_to_stereo8(void *dest, void *src, long count) {
  61.     unsigned char c,*s = (unsigned char *)src;
  62.     unsigned char *d = (unsigned char *)dest;
  63.  
  64.     do {
  65.         c = *s++;
  66.         *d++ = c;
  67.         *d++ = c;
  68.     } while(--count);
  69. }
  70.  
  71. static void convert_audio_mono8_to_stereo16(void *dest, void *src, long count) {
  72.     unsigned char *s = (unsigned char *)src;
  73.     unsigned long c, *d = (unsigned long *)dest;
  74.  
  75.     do {
  76.         c = ((*s++-0x80)&0xff) << 8;
  77.         *d++ = c | (c<<16);
  78.     } while(--count);
  79. }
  80.  
  81. static void convert_audio_mono16_to_mono8(void *dest, void *src, long count) {
  82.     signed short *s = (signed short *)src;
  83.     unsigned char *d = (unsigned char *)dest;
  84.  
  85.     do {
  86.         *d++ = (unsigned char)((((unsigned long)*s++)+0x8000)>>8);
  87.     } while(--count);
  88. }
  89.  
  90. static void convert_audio_mono16_to_stereo8(void *dest, void *src, long count) {
  91.     signed short *s = (signed short *)src;
  92.     unsigned char c, *d = (unsigned char *)dest;
  93.  
  94.     do {
  95.         c = (unsigned char)((((unsigned long)*s++)+0x8000)>>8);
  96.         *d++ = c;
  97.         *d++ = c;
  98.     } while(--count);
  99. }
  100.  
  101. static void convert_audio_mono16_to_stereo16(void *dest, void *src, long count) {
  102.     signed short *s = (signed short *)src;
  103.     unsigned long *d = (unsigned long *)dest, c;
  104.  
  105.     do {
  106.         c = *s++;
  107.         *d++ = (unsigned short)(c | (c<<16));
  108.     } while(--count);
  109. }
  110.  
  111. static void convert_audio_stereo8_to_mono8(void *dest, void *src, long count) {
  112.     unsigned short *s = (unsigned short *)src;
  113.     unsigned char *d = (unsigned char *)dest;
  114.     unsigned long c;
  115.  
  116.     do {
  117.         c = *s++;
  118.         *d++ = (unsigned char)(((c&0xff) + (c>>8))/2);
  119.     } while(--count);
  120. }
  121.  
  122. static void convert_audio_stereo8_to_mono16(void *dest, void *src, long count) {
  123.     unsigned short *s = (unsigned short *)src;
  124.     signed short *d = (signed short *)dest;
  125.     unsigned long c;
  126.  
  127.     do {
  128.         c = *s++;
  129.         *d++ = (signed short)((((c&0xff) + (c>>8))<<7)-0x8000);
  130.     } while(--count);
  131. }
  132.  
  133. static void convert_audio_stereo8_to_stereo16(void *dest, void *src, long count) {
  134.     unsigned short c,*s = (unsigned short *)src;
  135.     unsigned long *d = (unsigned long *)dest;
  136.  
  137.     do {
  138.         c = *s++;
  139.         *d++ = ((unsigned long)((c-0x80)&0xff)<<8) | ((unsigned long)((c&0xff00)-0x8000)<<16);
  140.     } while(--count);
  141. }
  142.  
  143. static void convert_audio_stereo16_to_mono8(void *dest, void *src, long count) {
  144.     unsigned long c, *s = (unsigned long *)src;
  145.     unsigned char *d = (unsigned char *)dest;
  146.  
  147.     do {
  148.         c = *s++;
  149.         *d++ = (unsigned char)(((((c&0xffff)+0xffff8000)^0xffff8000) + ((signed long)c>>16) + 0x10000)>>9);
  150.     } while(--count);
  151. }
  152.  
  153. static void convert_audio_stereo16_to_mono16(void *dest, void *src, long count) {
  154.     unsigned long c, *s = (unsigned long *)src;
  155.     signed short *d = (signed short *)dest;
  156.  
  157.     do {
  158.         c = *s++;
  159.         *d++ = (signed short)(((((c&0xffff)+0xffff8000)^0xffff8000) + ((signed long)c>>16))/2);
  160.     } while(--count);
  161. }
  162.  
  163. static void convert_audio_stereo16_to_stereo8(void *dest, void *src, long count) {
  164.     unsigned long c,*s = (unsigned long *)src;
  165.     unsigned char *d = (unsigned char *)dest;
  166.  
  167.     do {
  168.         c = *s++;
  169.         *d++ = (unsigned char)((((unsigned long)(c & 0xffff))+0x8000)>>8);
  170.         *d++ = (unsigned char)((((unsigned long)(c>>16))+0x8000)>>8);
  171.     } while(--count);
  172. }
  173.  
  174. static void convert_audio_dual8_to_mono8(void *dest, void *src, long count) {
  175.     const unsigned char *s = (unsigned char *)src;
  176.     unsigned char *d = (unsigned char *)dest;
  177.  
  178.     do {
  179.         *d++ = *s;
  180.         s+=2;
  181.     } while(--count);
  182. }
  183.  
  184. static void convert_audio_dual8_to_mono16(void *dest, void *src, long count) {
  185.     unsigned char *s = (unsigned char *)src;
  186.     signed short *d = (signed short *)dest;
  187.  
  188.     do {
  189.         *d++ = (signed short)((unsigned long)(*s-0x80)<<8);
  190.         s += 2;
  191.     } while(--count);
  192. }
  193.  
  194. static void convert_audio_dual16_to_mono8(void *dest, void *src, long count) {
  195.     signed short *s = (signed short *)src;
  196.     unsigned char *d = (unsigned char *)dest;
  197.  
  198.     do {
  199.         *d++ = (unsigned char)((((unsigned long)*s)+0x8000)>>8);
  200.         s += 2;
  201.     } while(--count);
  202. }
  203.  
  204. static void convert_audio_dual16_to_mono16(void *dest, void *src, long count) {
  205.     const signed short *s = (signed short *)src;
  206.     signed short *d = (signed short *)dest;
  207.  
  208.     do {
  209.         *d++ = *s;
  210.         s+=2;
  211.     } while(--count);
  212. }
  213.  
  214. ////////////////////////////////////////////
  215.  
  216. static const AudioFormatConverter acv[]={
  217.     convert_audio_nochange8,
  218.     convert_audio_mono8_to_mono16,
  219.     convert_audio_mono8_to_stereo8,
  220.     convert_audio_mono8_to_stereo16,
  221.     convert_audio_mono16_to_mono8,
  222.     convert_audio_nochange16,
  223.     convert_audio_mono16_to_stereo8,
  224.     convert_audio_mono16_to_stereo16,
  225.     convert_audio_stereo8_to_mono8,
  226.     convert_audio_stereo8_to_mono16,
  227.     convert_audio_nochange16,
  228.     convert_audio_stereo8_to_stereo16,
  229.     convert_audio_stereo16_to_mono8,
  230.     convert_audio_stereo16_to_mono16,
  231.     convert_audio_stereo16_to_stereo8,
  232.     convert_audio_nochange32,
  233. };
  234.  
  235. static const AudioFormatConverter acv2[]={
  236.     convert_audio_nochange8,
  237.     convert_audio_mono8_to_mono16,
  238.     convert_audio_mono16_to_mono8,
  239.     convert_audio_nochange16,
  240.     convert_audio_dual8_to_mono8,
  241.     convert_audio_dual8_to_mono16,
  242.     convert_audio_dual16_to_mono8,
  243.     convert_audio_dual16_to_mono16,
  244. };
  245.  
  246. AudioFormatConverter AudioPickConverter(WAVEFORMATEX *src, BOOL to_16bit, BOOL to_stereo) {
  247.     return acv[
  248.               (src->nChannels>1 ? 8 : 0)
  249.              +(src->wBitsPerSample>8 ? 4 : 0)
  250.              +(to_stereo ? 2 : 0)
  251.              +(to_16bit ? 1 : 0)
  252.         ];
  253. }
  254.  
  255. AudioFormatConverter AudioPickConverterSingleChannel(WAVEFORMATEX *src, bool to_16bit) {
  256.     return acv2[
  257.               (src->nChannels>1 ? 4 : 0)
  258.              +(src->wBitsPerSample>8 ? 2 : 0)
  259.              +(to_16bit ? 1 : 0)
  260.         ];
  261. }
  262.  
  263. ///////////////////////////////////
  264.  
  265. AudioStream::AudioStream() {
  266.     format = NULL;
  267.     format_len = 0;
  268.     samples_read = 0;
  269.     stream_limit = 0x7FFFFFFF;
  270. }
  271.  
  272. AudioStream::~AudioStream() {
  273.     freemem(format);
  274. }
  275.  
  276. WAVEFORMATEX *AudioStream::AllocFormat(long len) {
  277.     if (format) { freemem(format); format = 0; }
  278.  
  279.     if (!(format = (WAVEFORMATEX *)allocmem(len)))
  280.         throw MyError("AudioStream: Out of memory");
  281.  
  282.     format_len = len;
  283.  
  284.     return format;
  285. }
  286.  
  287. WAVEFORMATEX *AudioStream::GetFormat() {
  288.     return format;
  289. }
  290.  
  291. long AudioStream::GetFormatLen() {
  292.     return format_len;
  293. }
  294.  
  295. long AudioStream::GetSampleCount() {
  296.     return samples_read;
  297. }
  298.  
  299. long AudioStream::GetLength() {
  300.     return stream_limit < stream_len ? stream_limit : stream_len;
  301. }
  302.  
  303. long AudioStream::Read(void *buffer, long max_samples, long *lplBytes) {
  304.     long actual;
  305.  
  306.     if (max_samples <= 0) {
  307.         *lplBytes = 0;
  308.         return 0;
  309.     }
  310.  
  311.     if (samples_read >= stream_limit) {
  312.         *lplBytes = 0;
  313.         return 0;
  314.     }
  315.  
  316.     if (samples_read + max_samples > stream_limit)
  317.         max_samples = stream_limit - samples_read;
  318.  
  319.     actual = _Read(buffer, max_samples, lplBytes);
  320.  
  321.     _ASSERT(actual >= 0 && actual <= max_samples);
  322.  
  323.     samples_read += actual;
  324.  
  325.     return actual;
  326. }
  327.  
  328. bool AudioStream::Skip(long samples) {
  329.     return false;
  330. }
  331.  
  332. void AudioStream::SetLimit(long limit) {
  333.     _RPT1(0,"AudioStream: limit set to %ld\n",limit);
  334.     stream_limit = limit;
  335. }
  336.  
  337. void AudioStream::SetSource(AudioStream *src) {
  338.     source = src;
  339.     stream_len = src->GetLength();
  340. }
  341.  
  342. BOOL AudioStream::isEnd() {
  343.     return samples_read >= stream_limit || _isEnd();
  344. }
  345.  
  346. long AudioStream::_Read(void *buffer, long max_samples, long *lplBytes) {
  347.     *lplBytes = 0;
  348.  
  349.     return 0;
  350. }
  351.  
  352. BOOL AudioStream::_isEnd() {
  353.     return FALSE;
  354. }
  355.  
  356. ////////////////////
  357.  
  358. AudioStreamSource::AudioStreamSource(AudioSource *src, long first_samp, long max_samples, BOOL allow_decompression) : AudioStream() {
  359.     WAVEFORMATEX *iFormat = src->getWaveFormat();
  360.     WAVEFORMATEX *oFormat;
  361.     MMRESULT res;
  362.  
  363.     hACStream = NULL;
  364.     inputBuffer = outputBuffer = NULL;
  365.     fZeroRead = false;
  366.     fStart = true;
  367.     pwfexTempInput = NULL;
  368.     lPreskip = 0;
  369.  
  370.     if (max_samples < 0)
  371.         max_samples = 0;
  372.  
  373.     if (iFormat->wFormatTag != WAVE_FORMAT_PCM && allow_decompression) {
  374.         DWORD dwOutputBufferSize;
  375.         DWORD dwOutputFormatSize;
  376.  
  377.         if (!AllocFormat(sizeof(PCMWAVEFORMAT)))
  378.             throw MyMemoryError();
  379.  
  380.         if (acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, (LPVOID)&dwOutputFormatSize))
  381.             throw MyError("Couldn't get ACM's max format size");
  382.  
  383.         oFormat = (WAVEFORMATEX *)allocmem(dwOutputFormatSize); //AllocFormat(dwOutputFormatSize);
  384.         if (!oFormat) throw MyMemoryError();
  385.         oFormat->wFormatTag            = WAVE_FORMAT_PCM;
  386.  
  387.         if (acmFormatSuggest(NULL, iFormat, oFormat, dwOutputFormatSize, ACM_FORMATSUGGESTF_WFORMATTAG)) {
  388.             freemem(oFormat);
  389.             throw MyError("ACM failed to suggest audio decompression format");
  390.         }
  391.  
  392.         if (oFormat->wBitsPerSample!=8 && oFormat->wBitsPerSample!=16)
  393.                 oFormat->wBitsPerSample=16;
  394.  
  395.         if (oFormat->nChannels!=1 && oFormat->nChannels!=2)
  396.             oFormat->nChannels = 2;
  397.  
  398.         oFormat->nBlockAlign        = (oFormat->wBitsPerSample/8) * oFormat->nChannels;
  399.         oFormat->nAvgBytesPerSec    = oFormat->nBlockAlign * oFormat->nSamplesPerSec;
  400.         oFormat->cbSize                = 0;
  401.  
  402.         memcpy(GetFormat(), oFormat, sizeof(PCMWAVEFORMAT));
  403.         freemem(oFormat);
  404.         oFormat = GetFormat();
  405.  
  406.         memset(&ashBuffer, 0, sizeof ashBuffer);
  407.  
  408.         res = acmStreamOpen(&hACStream, NULL, iFormat, oFormat, NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME);
  409.  
  410.         if (res) {
  411.             if (res == ACMERR_NOTPOSSIBLE) {
  412.                 throw MyError(
  413.                             "Error initializing audio stream decompression:\n"
  414.                             "The requested conversion is not possible.\n"
  415.                             "\n"
  416.                             "Check to make sure you have the required codec%s."
  417.                             ,
  418.                             (iFormat->wFormatTag&~1)==0x160 ? " (Microsoft Audio Codec)" : ""
  419.                         );
  420.             } else
  421.                 throw MyError("Error initializing audio stream decompression.");
  422.         }
  423.  
  424.         if (acmStreamSize(hACStream, INPUT_BUFFER_SIZE, &dwOutputBufferSize, ACM_STREAMSIZEF_SOURCE))
  425.             throw MyError("Error initializing audio stream output size.");
  426.  
  427.         if (!(inputBuffer = allocmem(INPUT_BUFFER_SIZE))
  428.             || !(outputBuffer = allocmem(dwOutputBufferSize)))
  429.  
  430.             throw MyMemoryError();
  431.  
  432.         ashBuffer.cbStruct        = sizeof(ACMSTREAMHEADER);
  433.         ashBuffer.pbSrc            = (LPBYTE)inputBuffer;
  434.         ashBuffer.cbSrcLength    = INPUT_BUFFER_SIZE;
  435.         ashBuffer.pbDst            = (LPBYTE)outputBuffer;
  436.         ashBuffer.cbDstLength    = dwOutputBufferSize;
  437.  
  438.         if (acmStreamPrepareHeader(hACStream, &ashBuffer, 0))
  439.             throw MyError("Error preparing audio decompression buffers.");
  440.  
  441.         ashBuffer.cbSrcLength = 0;
  442.         ashBuffer.cbDstLengthUsed = 0;
  443.     } else {
  444.  
  445.         // FIX: If we have a PCMWAVEFORMAT stream, artificially cut the format size
  446.         //        to sizeof(PCMWAVEFORMAT).  LSX-MPEG Encoder doesn't like large PCM
  447.         //        formats!
  448.  
  449.         if (iFormat->wFormatTag == WAVE_FORMAT_PCM) {
  450.             oFormat = AllocFormat(sizeof(PCMWAVEFORMAT));
  451.             memcpy(oFormat, iFormat, sizeof(PCMWAVEFORMAT));
  452.         } else {
  453.             oFormat = AllocFormat(src->getFormatLen());
  454.             memcpy(oFormat, iFormat, GetFormatLen());
  455.         }
  456.     }
  457.  
  458.     aSrc = src;
  459.     stream_len = min(max_samples, aSrc->lSampleLast - first_samp);
  460.  
  461.     if (hACStream) {
  462.         stream_len = MulDiv(stream_len, GetFormat()->nSamplesPerSec * aSrc->getWaveFormat()->nBlockAlign, aSrc->getWaveFormat()->nAvgBytesPerSec);
  463.     }
  464.  
  465.     cur_samp = first_samp;
  466.     end_samp = first_samp + max_samples;
  467.  
  468. }
  469.  
  470. AudioStreamSource::~AudioStreamSource() {
  471.     if (hACStream) {
  472.         if (ashBuffer.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED) {
  473.             ashBuffer.cbSrcLength = INPUT_BUFFER_SIZE;
  474.             acmStreamUnprepareHeader(hACStream, &ashBuffer, 0);
  475.         }
  476.         acmStreamClose(hACStream, 0);
  477.     }
  478.     if (inputBuffer)    freemem(inputBuffer);
  479.     if (outputBuffer)    freemem(outputBuffer);
  480.     delete[] pwfexTempInput;
  481. }
  482.  
  483. long AudioStreamSource::_Read(void *buffer, long max_samples, long *lplBytes) {
  484.     LONG lSamples=0;
  485.     LONG lAddedBytes=0;
  486.     LONG lAddedSamples=0;
  487.     int err;
  488.     MMRESULT res;
  489.  
  490.     // add filler samples as necessary
  491.  
  492.     if (cur_samp < 0) {
  493.         long tc = -cur_samp;
  494.         const int nBlockAlign = aSrc->getWaveFormat()->nBlockAlign;
  495.  
  496.         if (tc > max_samples)
  497.             tc = max_samples;
  498.  
  499.         if (GetFormat()->nChannels > 1)
  500.             memset(buffer, 0, nBlockAlign*tc);
  501.         else
  502.             memset(buffer, 0x80, nBlockAlign*tc);
  503.  
  504.         buffer = (char *)buffer + nBlockAlign*tc;
  505.  
  506.         max_samples -= tc;
  507.         lAddedBytes = tc*nBlockAlign;
  508.         lAddedSamples = tc;
  509.         cur_samp += tc;
  510.     }
  511.  
  512.     // read actual samples
  513.  
  514.     if (hACStream) {
  515.         LONG ltActualBytes, ltActualSamples;
  516.         LONG lBytesLeft = max_samples * GetFormat()->nBlockAlign;
  517.         LONG lTotalBytes = lBytesLeft;
  518.         const int nBlockAlign = aSrc->getWaveFormat()->nBlockAlign;
  519.  
  520.         while(lBytesLeft > 0) {
  521.             // hmm... data still in the output buffer?
  522.  
  523.             if (ashBuffer.cbDstLengthUsed>0) {
  524.                 long tc = min(lBytesLeft, ashBuffer.cbDstLengthUsed);
  525.  
  526.                 if (lPreskip) {
  527.                     if (tc > lPreskip)
  528.                         tc = lPreskip;
  529.  
  530.                     lPreskip -= tc;
  531.                 } else {
  532.                     memcpy(buffer, outputBufferPtr, tc);
  533.                     buffer = (void *)((char *)buffer + tc);
  534.                     lBytesLeft -= tc;
  535.                 }
  536.  
  537.                 outputBufferPtr += tc;
  538.                 ashBuffer.cbDstLengthUsed -= tc;
  539.                 continue;
  540.             }
  541.  
  542.             // fill the input buffer up... if we haven't gotten a zero yet.
  543.  
  544.             if (ashBuffer.cbSrcLength < INPUT_BUFFER_SIZE && !fZeroRead) {
  545.                 LONG lBytes=0;
  546.  
  547.                 do {
  548.                     LONG to_read = (INPUT_BUFFER_SIZE - ashBuffer.cbSrcLength)/nBlockAlign;
  549.  
  550.                     if (to_read > end_samp - cur_samp)
  551.                         to_read = end_samp - cur_samp;
  552.  
  553.                     err = aSrc->read(cur_samp, to_read, (char *)inputBuffer + ashBuffer.cbSrcLength, INPUT_BUFFER_SIZE - ashBuffer.cbSrcLength, <ActualBytes, <ActualSamples);
  554.  
  555.                     if (err != AVIERR_OK && err != AVIERR_BUFFERTOOSMALL)
  556.                         throw MyAVIError("AudioStreamSource", err);
  557.  
  558.                     cur_samp += ltActualSamples;
  559.  
  560. //                    _RPT1(0,"Read to %ld\n", cur_samp);
  561.  
  562.                     ashBuffer.cbSrcLength += ltActualBytes;
  563.  
  564.                     lBytes += ltActualBytes;
  565.  
  566.                 } while(err != AVIERR_BUFFERTOOSMALL && ashBuffer.cbSrcLength < INPUT_BUFFER_SIZE && ltActualBytes && cur_samp < end_samp);
  567.  
  568.                 if (!lBytes) fZeroRead = true;
  569.             }
  570.  
  571.             // ask ACM to convert for us
  572.  
  573.             ashBuffer.cbSrcLengthUsed = 0;
  574.             ashBuffer.cbDstLengthUsed = 0;
  575.  
  576.     VDCHECKPOINT;
  577.             if (ashBuffer.cbSrcLength)
  578.                 if (res = acmStreamConvert(hACStream, &ashBuffer, (fStart ? ACM_STREAMCONVERTF_START : 0) | ACM_STREAMCONVERTF_BLOCKALIGN))
  579.                     throw MyError("ACM reported error on audio decompress (%lx)", res);
  580.     VDCHECKPOINT;
  581.  
  582.             fStart = false;
  583.  
  584.             _RPT2(0,"Converted %ld bytes to %ld\n", ashBuffer.cbSrcLengthUsed, ashBuffer.cbDstLengthUsed);
  585.  
  586.             if (!ashBuffer.cbSrcLengthUsed && fZeroRead)
  587.                 break;
  588.  
  589.             // if ACM didn't use all the source data, copy the remainder down
  590.  
  591.             if (ashBuffer.cbSrcLengthUsed < ashBuffer.cbSrcLength) {
  592.                 long left = ashBuffer.cbSrcLength - ashBuffer.cbSrcLengthUsed;
  593.  
  594.                 memmove(inputBuffer, (char *)inputBuffer + ashBuffer.cbSrcLengthUsed, left);
  595.  
  596.                 ashBuffer.cbSrcLength = left;
  597.             } else
  598.                 ashBuffer.cbSrcLength = 0;
  599.  
  600.             outputBufferPtr = (char *)outputBuffer;
  601.         };
  602.  
  603.         *lplBytes = (lTotalBytes - lBytesLeft) + lAddedBytes;
  604.  
  605.         return *lplBytes / GetFormat()->nBlockAlign + lAddedSamples;
  606.     } else {
  607.         if (max_samples > end_samp - cur_samp)
  608.             max_samples = end_samp - cur_samp;
  609.  
  610.         if (max_samples) {
  611.             if (AVIERR_OK != (err = aSrc->read(cur_samp, max_samples, buffer, 0x7FFFFFFFL, lplBytes, &lSamples)))
  612.                 throw MyAVIError("AudioStreamSource", err);
  613.  
  614.             if (!lSamples) fZeroRead = true;
  615.         } else
  616.             lSamples = *lplBytes = 0;
  617.  
  618.         *lplBytes += lAddedBytes;
  619.  
  620.         cur_samp += lSamples;
  621.  
  622.         return lSamples + lAddedSamples;
  623.     }
  624. }
  625.  
  626. bool AudioStreamSource::Skip(long samples) {
  627.  
  628.     // nBlockAlign = bytes per block.
  629.     //
  630.     // nAvgBytesPerSec / nBlockAlign = blocks per second.
  631.     // nSamplesPerSec * nBlockAlign / nAvgBytesPerSec = samples per block.
  632.  
  633.     if (hACStream) {
  634.         const WAVEFORMATEX *pwfex = aSrc->getWaveFormat();
  635.  
  636.         if (samples < MulDiv(4*pwfex->nBlockAlign, pwfex->nSamplesPerSec, pwfex->nAvgBytesPerSec)) {
  637.             lPreskip += samples*GetFormat()->nBlockAlign;
  638.             return true;
  639.         }
  640.  
  641.         // Flush input and output buffers.
  642.  
  643.         ashBuffer.cbSrcLength = 0;
  644.         ashBuffer.cbDstLengthUsed = 0;
  645.  
  646.         // Trigger a reseek.
  647.  
  648.         long new_pos = ((samples_read + samples) * (__int64)pwfex->nAvgBytesPerSec) / ((__int64)pwfex->nBlockAlign*pwfex->nSamplesPerSec);
  649.  
  650.         if (new_pos > cur_samp)
  651.             cur_samp = new_pos;
  652.  
  653.         fStart = true;
  654.  
  655.         // Skip fractional samples.
  656.  
  657.         long samp_start = (new_pos * (__int64)pwfex->nSamplesPerSec*pwfex->nBlockAlign) / pwfex->nAvgBytesPerSec;
  658.  
  659.         lPreskip = ((samples_read + samples) - samp_start)*GetFormat()->nBlockAlign;
  660.  
  661.         samples_read = samp_start;
  662.  
  663.         return true;
  664.  
  665.     } else {
  666.         cur_samp += samples;
  667.         samples_read += samples;
  668.  
  669.         return true;
  670.     }
  671. }
  672.  
  673. BOOL AudioStreamSource::_isEnd() {
  674.     return (cur_samp >= end_samp || fZeroRead) && (!hACStream || !ashBuffer.cbDstLengthUsed);
  675. }
  676.  
  677.  
  678.  
  679. ///////////////////////////////////////////////////////////////////////////
  680. //
  681. //        AudioStreamConverter
  682. //
  683. //        This audio filter handles changes in format between 8/16-bit
  684. //        and mono/stereo.
  685. //
  686. ///////////////////////////////////////////////////////////////////////////
  687.  
  688.  
  689.  
  690. AudioStreamConverter::AudioStreamConverter(AudioStream *src, bool to_16bit, bool to_stereo_or_right, bool single_only) {
  691.     WAVEFORMATEX *iFormat = src->GetFormat();
  692.     WAVEFORMATEX *oFormat;
  693.     bool to_stereo = single_only ? false : to_stereo_or_right;
  694.  
  695.     memcpy(oFormat = AllocFormat(src->GetFormatLen()), iFormat, src->GetFormatLen());
  696.  
  697.     oFormat->nChannels = to_stereo ? 2 : 1;
  698.     oFormat->wBitsPerSample = to_16bit ? 16 : 8;
  699.  
  700.     bytesPerInputSample = (iFormat->nChannels>1 ? 2 : 1)
  701.                         * (iFormat->wBitsPerSample>8 ? 2 : 1);
  702.  
  703.     bytesPerOutputSample = (to_stereo ? 2 : 1)
  704.                          * (to_16bit ? 2 : 1);
  705.  
  706.     offset = 0;
  707.  
  708.     if (single_only) {
  709.         convRout = AudioPickConverterSingleChannel(iFormat, to_16bit);
  710.  
  711.         if (to_stereo_or_right && iFormat->nChannels>1) {
  712.             offset = 1;
  713.  
  714.             if (iFormat->wBitsPerSample>8)
  715.                 offset = 2;
  716.         }
  717.     } else
  718.         convRout = AudioPickConverter(iFormat, to_16bit, to_stereo);
  719.     SetSource(src);
  720.  
  721.     oFormat->nAvgBytesPerSec = oFormat->nSamplesPerSec * bytesPerOutputSample;
  722.     oFormat->nBlockAlign = bytesPerOutputSample;
  723.  
  724.  
  725.     if (!(cbuffer = allocmem(bytesPerInputSample * BUFFER_SIZE)))
  726.         throw MyError("AudioStreamConverter: out of memory");
  727. }
  728.  
  729. AudioStreamConverter::~AudioStreamConverter() {
  730.     freemem(cbuffer);
  731. }
  732.  
  733. long AudioStreamConverter::_Read(void *buffer, long samples, long *lplBytes) {
  734.     long lActualSamples=0;
  735.  
  736.     while(samples>0) {
  737.         long srcSamples;
  738.         long lBytes;
  739.  
  740.         // figure out how many source samples we need
  741.  
  742.         srcSamples = samples;
  743.  
  744.         if (srcSamples > BUFFER_SIZE) srcSamples = BUFFER_SIZE;
  745.  
  746.         srcSamples = source->Read(cbuffer, srcSamples, &lBytes);
  747.  
  748.         if (!srcSamples) break;
  749.  
  750.         convRout(buffer, (char *)cbuffer + offset, srcSamples);
  751.  
  752.         buffer = (void *)((char *)buffer + bytesPerOutputSample * srcSamples);
  753.         lActualSamples += srcSamples;
  754.         samples -= srcSamples;
  755.  
  756.     }
  757.  
  758.     *lplBytes = lActualSamples * bytesPerOutputSample;
  759.  
  760.     return lActualSamples;
  761. }
  762.  
  763. BOOL AudioStreamConverter::_isEnd() {
  764.     return source->isEnd();
  765. }
  766.  
  767.  
  768.  
  769. ///////////////////////////////////////////////////////////////////////////
  770. //
  771. //        AudioStreamResampler
  772. //
  773. //        This audio filter handles changes in sampling rate.
  774. //
  775. ///////////////////////////////////////////////////////////////////////////
  776.  
  777. static long audio_pointsample_8(void *dst, void *src, long accum, long samp_frac, long cnt) {
  778.     unsigned char *d = (unsigned char *)dst;
  779.     unsigned char *s = (unsigned char *)src;
  780.  
  781.     do {
  782.         *d++ = s[accum>>19];
  783.         accum += samp_frac;
  784.     } while(--cnt);
  785.  
  786.     return accum;
  787. }
  788.  
  789. static long audio_pointsample_16(void *dst, void *src, long accum, long samp_frac, long cnt) {
  790.     unsigned short *d = (unsigned short *)dst;
  791.     unsigned short *s = (unsigned short *)src;
  792.  
  793.     do {
  794.         *d++ = s[accum>>19];
  795.         accum += samp_frac;
  796.     } while(--cnt);
  797.  
  798.     return accum;
  799. }
  800.  
  801. static long audio_pointsample_32(void *dst, void *src, long accum, long samp_frac, long cnt) {
  802.     unsigned long *d = (unsigned long *)dst;
  803.     unsigned long *s = (unsigned long *)src;
  804.  
  805.     do {
  806.         *d++ = s[accum>>19];
  807.         accum += samp_frac;
  808.     } while(--cnt);
  809.  
  810.     return accum;
  811. }
  812.  
  813. static long audio_downsample_mono8(void *dst, void *src, long *filter_bank, int filter_width, long accum, long samp_frac, long cnt) {
  814.     unsigned char *d = (unsigned char *)dst;
  815.     unsigned char *s = (unsigned char *)src;
  816.  
  817.     do {
  818.         long sum = 0;
  819.         int w;
  820.         long *fb_ptr;
  821.         unsigned char *s_ptr;
  822.  
  823.         w = filter_width;
  824.         fb_ptr = filter_bank + filter_width * ((accum>>11)&0xff);
  825.         s_ptr = s + (accum>>19);
  826.         do {
  827.             sum += *fb_ptr++ * (int)*s_ptr++;
  828.         } while(--w);
  829.  
  830.         if (sum < 0)
  831.             *d++ = 0;
  832.         else if (sum > 0x3fffff)
  833.             *d++ = 0xff;
  834.         else
  835.             *d++ = ((sum + 0x2000)>>14);
  836.  
  837.         accum += samp_frac;
  838.     } while(--cnt);
  839.  
  840.     return accum;
  841. }
  842.  
  843. static long audio_downsample_mono16(void *dst, void *src, long *filter_bank, int filter_width, long accum, long samp_frac, long cnt) {
  844.     signed short *d = (signed short *)dst;
  845.     signed short *s = (signed short *)src;
  846.  
  847.     do {
  848.         long sum = 0;
  849.         int w;
  850.         long *fb_ptr;
  851.         signed short *s_ptr;
  852.  
  853.         w = filter_width;
  854.         fb_ptr = filter_bank + filter_width * ((accum>>11)&0xff);
  855.         s_ptr = s + (accum>>19);
  856.         do {
  857.             sum += *fb_ptr++ * (int)*s_ptr++;
  858.         } while(--w);
  859.  
  860.         if (sum < -0x20000000)
  861.             *d++ = -0x8000;
  862.         else if (sum > 0x1fffffff)
  863.             *d++ = 0x7fff;
  864.         else
  865.             *d++ = ((sum + 0x2000)>>14);
  866.  
  867.         accum += samp_frac;
  868.     } while(--cnt);
  869.  
  870.     return accum;
  871. }
  872.  
  873. static long audio_downsample_stereo8(void *dst, void *src, long *filter_bank, int filter_width, long accum, long samp_frac, long cnt) {
  874.     unsigned char *d = (unsigned char *)dst;
  875.     unsigned char *s = (unsigned char *)src;
  876.  
  877.     do {
  878.         long sum_l = 0, sum_r = 0;
  879.         int w;
  880.         long *fb_ptr;
  881.         unsigned char *s_ptr;
  882.  
  883.         w = filter_width;
  884.         fb_ptr = filter_bank + filter_width * ((accum>>11)&0xff);
  885.         s_ptr = s + (accum>>19)*2;
  886.         do {
  887.             long f = *fb_ptr++;
  888.  
  889.             sum_l += f * (int)*s_ptr++;
  890.             sum_r += f * (int)*s_ptr++;
  891.         } while(--w);
  892.  
  893.         if (sum_l < 0)
  894.             *d++ = 0;
  895.         else if (sum_l > 0x3fffff)
  896.             *d++ = 0xff;
  897.         else
  898.             *d++ = ((sum_l + 0x2000)>>14);
  899.  
  900.         if (sum_r < 0)
  901.             *d++ = 0;
  902.         else if (sum_r > 0x3fffff)
  903.             *d++ = 0xff;
  904.         else
  905.             *d++ = ((sum_r + 0x2000)>>14);
  906.  
  907.         accum += samp_frac;
  908.     } while(--cnt);
  909.  
  910.     return accum;
  911. }
  912.  
  913. static long audio_downsample_stereo16(void *dst, void *src, long *filter_bank, int filter_width, long accum, long samp_frac, long cnt) {
  914.     signed short *d = (signed short *)dst;
  915.     signed short *s = (signed short *)src;
  916.  
  917.     do {
  918.         long sum_l = 0, sum_r = 0;
  919.         int w;
  920.         long *fb_ptr;
  921.         signed short *s_ptr;
  922.  
  923.         w = filter_width;
  924.         fb_ptr = filter_bank + filter_width * ((accum>>11)&0xff);
  925.         s_ptr = s + (accum>>19)*2;
  926.         do {
  927.             long f = *fb_ptr++;
  928.  
  929.             sum_l += f * (int)*s_ptr++;
  930.             sum_r += f * (int)*s_ptr++;
  931.         } while(--w);
  932.  
  933.         if (sum_l < -0x20000000)
  934.             *d++ = -0x8000;
  935.         else if (sum_l > 0x1fffffff)
  936.             *d++ = 0x7fff;
  937.         else
  938.             *d++ = ((sum_l + 0x2000)>>14);
  939.  
  940.         if (sum_r < -0x20000000)
  941.             *d++ = -0x8000;
  942.         else if (sum_r > 0x1fffffff)
  943.             *d++ = 0x7fff;
  944.         else
  945.             *d++ = ((sum_r + 0x2000)>>14);
  946.  
  947.         accum += samp_frac;
  948.     } while(--cnt);
  949.  
  950.     return accum;
  951. }
  952.  
  953. static long audio_upsample_mono8(void *dst, void *src, long accum, long samp_frac, long cnt) {
  954.     unsigned char *d = (unsigned char *)dst;
  955.     unsigned char *s = (unsigned char *)src;
  956.  
  957.     do {
  958.         unsigned char *s_ptr = s + (accum>>19);
  959.         long frac = (accum>>3) & 0xffff;
  960.  
  961.         *d++ = ((int)s_ptr[0] * (0x10000 - frac) + (int)s_ptr[1] * frac) >> 16;
  962.         accum += samp_frac;
  963.     } while(--cnt);
  964.  
  965.     return accum;
  966. }
  967.  
  968. static long audio_upsample_mono16(void *dst, void *src, long accum, long samp_frac, long cnt) {
  969.     signed short *d = (signed short *)dst;
  970.     signed short *s = (signed short *)src;
  971.  
  972.     do {
  973.         signed short *s_ptr = s + (accum>>19);
  974.         long frac = (accum>>3) & 0xffff;
  975.  
  976.         *d++ = ((int)s_ptr[0] * (0x10000 - frac) + (int)s_ptr[1] * frac) >> 16;
  977.         accum += samp_frac;
  978.     } while(--cnt);
  979.  
  980.     return accum;
  981. }
  982.  
  983. static long audio_upsample_stereo8(void *dst, void *src, long accum, long samp_frac, long cnt) {
  984.     unsigned char *d = (unsigned char *)dst;
  985.     unsigned char *s = (unsigned char *)src;
  986.  
  987.     do {
  988.         unsigned char *s_ptr = s + (accum>>19)*2;
  989.         long frac = (accum>>3) & 0xffff;
  990.  
  991.         *d++ = ((int)s_ptr[0] * (0x10000 - frac) + (int)s_ptr[2] * frac) >> 16;
  992.         *d++ = ((int)s_ptr[1] * (0x10000 - frac) + (int)s_ptr[3] * frac) >> 16;
  993.         accum += samp_frac;
  994.     } while(--cnt);
  995.  
  996.     return accum;
  997. }
  998.  
  999. static long audio_upsample_stereo16(void *dst, void *src, long accum, long samp_frac, long cnt) {
  1000.     signed short *d = (signed short *)dst;
  1001.     signed short *s = (signed short *)src;
  1002.  
  1003.     do {
  1004.         signed short *s_ptr = s + (accum>>19)*2;
  1005.         long frac = (accum>>3) & 0xffff;
  1006.  
  1007.         *d++ = ((int)s_ptr[0] * (0x10000 - frac) + (int)s_ptr[2] * frac) >> 16;
  1008.         *d++ = ((int)s_ptr[1] * (0x10000 - frac) + (int)s_ptr[3] * frac) >> 16;
  1009.         accum += samp_frac;
  1010.     } while(--cnt);
  1011.  
  1012.     return accum;
  1013. }
  1014.  
  1015. static int permute_index(int a, int b) {
  1016.     return (b-(a>>8)-1) + (a&255)*b;
  1017. }
  1018.  
  1019. static void make_downsample_filter(long *filter_bank, int filter_width, long samp_frac) {
  1020.     int i, j, v;
  1021.     double filt_max;
  1022.     double filtwidth_frac;
  1023.  
  1024.     filtwidth_frac = samp_frac/2048.0;
  1025.  
  1026.     filter_bank[filter_width-1] = 0;
  1027.  
  1028.     filt_max = (16384.0 * 524288.0) / samp_frac;
  1029.  
  1030.     for(i=0; i<128*filter_width; i++) {
  1031.         int y = 0;
  1032.         double d = i / filtwidth_frac;
  1033.  
  1034.         if (d<1.0)
  1035.             y = (int)(0.5 + filt_max*(1.0 - d));
  1036.  
  1037.         filter_bank[permute_index(128*filter_width + i, filter_width)]
  1038.             = filter_bank[permute_index(128*filter_width - i, filter_width)]
  1039.             = y;
  1040.     }
  1041.  
  1042.     // Normalize the filter to correct for integer roundoff errors
  1043.  
  1044.     for(i=0; i<256*filter_width; i+=filter_width) {
  1045.         v=0;
  1046.         for(j=0; j<filter_width; j++)
  1047.             v += filter_bank[i+j];
  1048.  
  1049.         _RPT2(0,"error[%02x] = %04x\n", i/filter_width, 0x4000 - v);
  1050.  
  1051.         v = (0x4000 - v)/filter_width;
  1052.         for(j=0; j<filter_width; j++)
  1053.             filter_bank[i+j] += v;
  1054.     }
  1055.  
  1056.     _CrtCheckMemory();
  1057. }
  1058.  
  1059. AudioStreamResampler::AudioStreamResampler(AudioStream *src, long new_rate, bool integral_conversion, bool hi_quality) : AudioStream() {
  1060.     WAVEFORMATEX *iFormat = src->GetFormat();
  1061.     WAVEFORMATEX *oFormat;
  1062.  
  1063.     memcpy(oFormat = AllocFormat(src->GetFormatLen()), iFormat, src->GetFormatLen());
  1064.  
  1065.     if (oFormat->nChannels>1)
  1066.         if (oFormat->wBitsPerSample>8) {
  1067.             ptsampleRout = audio_pointsample_32;
  1068.             upsampleRout = audio_upsample_stereo16;
  1069.             dnsampleRout = audio_downsample_stereo16;
  1070.         } else {
  1071.             ptsampleRout = audio_pointsample_16;
  1072.             upsampleRout = audio_upsample_stereo8;
  1073.             dnsampleRout = audio_downsample_stereo8;
  1074.         }
  1075.     else
  1076.         if (oFormat->wBitsPerSample>8) {
  1077.             ptsampleRout = audio_pointsample_16;
  1078.             upsampleRout = audio_upsample_mono16;
  1079.             dnsampleRout = audio_downsample_mono16;
  1080.         } else {
  1081.             ptsampleRout = audio_pointsample_8;
  1082.             upsampleRout = audio_upsample_mono8;
  1083.             dnsampleRout = audio_downsample_mono8;
  1084.         }
  1085.  
  1086.     SetSource(src);
  1087.  
  1088.     bytesPerSample = (iFormat->nChannels>1 ? 2 : 1)
  1089.                         * (iFormat->wBitsPerSample>8 ? 2 : 1);
  1090.  
  1091.     _RPT2(0,"AudioStreamResampler: converting from %ldHz to %ldHz\n", iFormat->nSamplesPerSec, new_rate);
  1092.  
  1093.     if (integral_conversion)
  1094.         if (new_rate > iFormat->nSamplesPerSec)
  1095. //            samp_frac = MulDiv(0x10000, new_rate + iFormat->nSamplesPerSec/2, iFormat->nSamplesPerSec);
  1096.             samp_frac = 0x80000 / ((new_rate + iFormat->nSamplesPerSec/2) / iFormat->nSamplesPerSec); 
  1097.         else
  1098.             samp_frac = 0x80000 * ((iFormat->nSamplesPerSec + new_rate/2) / new_rate);
  1099.     else
  1100.         samp_frac = MulDiv(iFormat->nSamplesPerSec, 0x80000L, new_rate);
  1101.  
  1102.     stream_len = MulDiv(stream_len, 0x80000L, samp_frac);
  1103.  
  1104.     oFormat->nSamplesPerSec = MulDiv(iFormat->nSamplesPerSec, 0x80000L, samp_frac);
  1105.     oFormat->nAvgBytesPerSec = oFormat->nSamplesPerSec * bytesPerSample;
  1106.     oFormat->nBlockAlign = bytesPerSample;
  1107.  
  1108.     holdover = 0;
  1109.     filter_bank = NULL;
  1110.     filter_width = 1;
  1111.     accum=0;
  1112.     fHighQuality = hi_quality;
  1113.  
  1114.     if (!(cbuffer = allocmem(bytesPerSample * BUFFER_SIZE)))
  1115.         throw MyMemoryError();
  1116.  
  1117.     // If this is a high-quality downsample, allocate memory for the filter bank
  1118.  
  1119.     if (hi_quality) {
  1120.         if (samp_frac>0x80000) {
  1121.  
  1122.             // HQ downsample: allocate filter bank
  1123.  
  1124.             filter_width = ((samp_frac + 0x7ffff)>>19)<<1;
  1125.  
  1126.             if (!(filter_bank = new long[filter_width * 256])) {
  1127.                 freemem(cbuffer);
  1128.                 throw MyMemoryError();
  1129.             }
  1130.  
  1131.             make_downsample_filter(filter_bank, filter_width, samp_frac);
  1132.  
  1133.             // Clear lower samples
  1134.  
  1135.             if (oFormat->wBitsPerSample>8)
  1136.                 memset(cbuffer, 0, bytesPerSample*filter_width);
  1137.             else
  1138.                 memset(cbuffer, 0x80, bytesPerSample*filter_width);
  1139.  
  1140.             holdover = filter_width/2;
  1141.         }
  1142.     }
  1143. }
  1144.  
  1145. AudioStreamResampler::~AudioStreamResampler() {
  1146.     freemem(cbuffer);
  1147.     delete filter_bank;
  1148. }
  1149.  
  1150. long AudioStreamResampler::_Read(void *buffer, long samples, long *lplBytes) {
  1151.  
  1152.     if (samp_frac == 0x80000)
  1153.         return source->Read(buffer, samples, lplBytes);
  1154.  
  1155.     if (samp_frac < 0x80000)
  1156.         return Upsample(buffer, samples, lplBytes);
  1157.     else
  1158.         return Downsample(buffer, samples, lplBytes);
  1159. }
  1160.  
  1161.  
  1162. long AudioStreamResampler::Upsample(void *buffer, long samples, long *lplBytes) {
  1163.     long lActualSamples=0;
  1164.  
  1165.     // Upsampling: producing more output samples than input
  1166.     //
  1167.     // There are two issues we need to watch here:
  1168.     //
  1169.     //    o  An input sample can be read more than once.  In particular, even
  1170.     //       when point sampling, we may need the last input sample again.
  1171.     //
  1172.     //    o  When interpolating (HQ), we need one additional sample.
  1173.  
  1174.     while(samples>0) {
  1175.         long srcSamples, dstSamples;
  1176.         long lBytes;
  1177.         int holdover = 0;
  1178.  
  1179.         // A negative accum value indicates that we need to reprocess a sample.
  1180.         // The last iteration should have left it at the bottom of the buffer
  1181.         // for us.  In interpolation mode, we'll always have at least a 1
  1182.         // sample overlap.
  1183.  
  1184.         if (accum<0) {
  1185.             holdover = 1;
  1186.             accum += 0x80000;
  1187.         }
  1188.  
  1189.         if (fHighQuality)
  1190.             ++holdover;
  1191.  
  1192.         // figure out how many source samples we need
  1193.  
  1194.         srcSamples = (long)(((__int64)samp_frac*(samples-1) + accum) >> 19) + 1 - holdover;
  1195.  
  1196.         if (fHighQuality)
  1197.             ++srcSamples;
  1198.  
  1199.         if (srcSamples > BUFFER_SIZE-holdover) srcSamples = BUFFER_SIZE-holdover;
  1200.  
  1201.         srcSamples = source->Read((char *)cbuffer + holdover * bytesPerSample, srcSamples, &lBytes);
  1202.  
  1203.         if (!srcSamples) break;
  1204.  
  1205.         srcSamples += holdover;
  1206.  
  1207.         // figure out how many destination samples we'll get out of what we read
  1208.  
  1209.         if (fHighQuality)
  1210.             dstSamples = ((srcSamples<<19) - accum - 0x80001)/samp_frac + 1;
  1211.         else
  1212.             dstSamples = ((srcSamples<<19) - accum - 1)/samp_frac + 1;
  1213.  
  1214.         if (dstSamples > samples)
  1215.             dstSamples = samples;
  1216.  
  1217.         if (dstSamples>=1) {
  1218.  
  1219.             if (fHighQuality)
  1220.                 accum = upsampleRout(buffer, cbuffer, accum, samp_frac, dstSamples);
  1221.             else
  1222.                 accum = ptsampleRout(buffer, cbuffer, accum, samp_frac, dstSamples);
  1223.  
  1224.             buffer = (void *)((char *)buffer + bytesPerSample * dstSamples);
  1225.             lActualSamples += dstSamples;
  1226.             samples -= dstSamples;
  1227.         }
  1228.  
  1229.         if (fHighQuality)
  1230.             accum -= ((srcSamples-1)<<19);
  1231.         else
  1232.             accum -= (srcSamples<<19);
  1233.  
  1234.         // do we need to hold a sample over?
  1235.  
  1236.         if (fHighQuality)
  1237.             if (accum<0)
  1238.                 memcpy(cbuffer, (char *)cbuffer + (srcSamples-2)*bytesPerSample, bytesPerSample*2);
  1239.             else
  1240.                 memcpy(cbuffer, (char *)cbuffer + (srcSamples-1)*bytesPerSample, bytesPerSample);
  1241.         else if (accum<0)
  1242.             memcpy(cbuffer, (char *)cbuffer + (srcSamples-1)*bytesPerSample, bytesPerSample);
  1243.     }
  1244.  
  1245.     *lplBytes = lActualSamples * bytesPerSample;
  1246.  
  1247. //    _RPT2(0,"Converter: %ld samples, %ld bytes\n", lActualSamples, *lplBytes);
  1248.  
  1249.     return lActualSamples;
  1250. }
  1251.  
  1252. long AudioStreamResampler::Downsample(void *buffer, long samples, long *lplBytes) {
  1253.     long lActualSamples=0;
  1254.  
  1255.     // Downsampling is even worse because we have overlap to the left and to the
  1256.     // right of the interpolated point.
  1257.     //
  1258.     // We need (n/2) points to the left and (n/2-1) points to the right.
  1259.  
  1260.     while(samples>0) {
  1261.         long srcSamples, dstSamples;
  1262.         long lBytes;
  1263.         int nhold;
  1264.  
  1265.         // Figure out how many source samples we need.
  1266.         //
  1267.         // To do this, compute the highest fixed-point accumulator we'll reach.
  1268.         // Truncate that, and add the filter width.  Then subtract however many
  1269.         // samples are sitting at the bottom of the buffer.
  1270.  
  1271.         srcSamples = (long)(((__int64)samp_frac*(samples-1) + accum) >> 19) + filter_width - holdover;
  1272.  
  1273.         // Don't exceed the buffer (BUFFER_SIZE - holdover).
  1274.  
  1275.         if (srcSamples > BUFFER_SIZE - holdover)
  1276.             srcSamples = BUFFER_SIZE - holdover;
  1277.  
  1278.         // Read into buffer.
  1279.  
  1280.         srcSamples = source->Read((char *)cbuffer + holdover*bytesPerSample, srcSamples, &lBytes);
  1281.  
  1282.         if (!srcSamples) break;
  1283.  
  1284.         // Figure out how many destination samples we'll get out of what we
  1285.         // read.  We'll have (srcSamples+holdover) bytes, so the maximum
  1286.         // fixed-pt accumulator we can hit is
  1287.         // (srcSamples+holdover-filter_width)<<16 + 0xffff.
  1288.  
  1289.         dstSamples = (((srcSamples+holdover-filter_width)<<19) + 0x7ffff - accum) / samp_frac + 1;
  1290.  
  1291.         if (dstSamples > samples)
  1292.             dstSamples = samples;
  1293.  
  1294.         if (dstSamples>=1) {
  1295.             if (filter_bank)
  1296.                 accum = dnsampleRout(buffer, cbuffer, filter_bank, filter_width, accum, samp_frac, dstSamples);
  1297.             else
  1298.                 accum = ptsampleRout(buffer, cbuffer, accum, samp_frac, dstSamples);
  1299.  
  1300.             buffer = (void *)((char *)buffer + bytesPerSample * dstSamples);
  1301.             lActualSamples += dstSamples;
  1302.             samples -= dstSamples;
  1303.         }
  1304.  
  1305.         // We're "shifting" the new samples down to the bottom by discarding
  1306.         // all the samples in the buffer, so adjust the fixed-pt accum
  1307.         // accordingly.
  1308.  
  1309.         accum -= ((srcSamples+holdover)<<19);
  1310.  
  1311.         // Oops, did we need some of those?
  1312.         //
  1313.         // If accum=0, we need (n/2) samples back.  accum>=0x10000 is fewer,
  1314.         // accum<0 is more.
  1315.  
  1316.         nhold = - (accum>>19);
  1317.  
  1318. //        _ASSERT(nhold<=(filter_width/2));
  1319.  
  1320.         if (nhold>0) {
  1321.             memmove(cbuffer, (char *)cbuffer+bytesPerSample*(srcSamples+holdover-nhold), bytesPerSample*nhold);
  1322.             holdover = nhold;
  1323.             accum += nhold<<19;
  1324.         } else
  1325.             holdover = 0;
  1326.  
  1327.         _ASSERT(accum>=0);
  1328.     }
  1329.  
  1330.     *lplBytes = lActualSamples * bytesPerSample;
  1331.  
  1332.     return lActualSamples;
  1333. }
  1334.  
  1335. BOOL AudioStreamResampler::_isEnd() {
  1336.     return accum>=0 && source->isEnd();
  1337. }
  1338.  
  1339.  
  1340.  
  1341. ///////////////////////////////////////////////////////////////////////////
  1342. //
  1343. //        AudioCompressor
  1344. //
  1345. //        This audio filter handles audio compression.
  1346. //
  1347. ///////////////////////////////////////////////////////////////////////////
  1348.  
  1349.  
  1350. struct FrustratedACMOpenData {
  1351.     HACMSTREAM *pp;
  1352.     HACMDRIVER hdrv;
  1353.     WAVEFORMATEX *iFormat;
  1354.     WAVEFORMATEX *oFormat;
  1355.     bool success;
  1356. };
  1357.  
  1358.  
  1359. BOOL CALLBACK ACMStreamOpenCallback(HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport) {
  1360.     FrustratedACMOpenData *pfad = (FrustratedACMOpenData *)dwInstance;
  1361.  
  1362.     // Ignore drivers that don't do format conversion.
  1363.  
  1364.     if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC) {
  1365.         MMRESULT res;
  1366.         ACMDRIVERDETAILS add;
  1367.  
  1368.         memset(&add, 0, sizeof add);
  1369.         add.cbStruct = sizeof add;
  1370.  
  1371.         // Attempt to open driver.
  1372.  
  1373.         res = acmDriverOpen(&pfad->hdrv, hadid, 0);
  1374.  
  1375.         if (!res) {
  1376.  
  1377.             res = acmDriverDetails(hadid, &add, 0);
  1378.             if (!res)
  1379.                 _RPT1(0,"Trying driver: [%s]\n", add.szLongName);
  1380.  
  1381.             // Attempt our stream open!
  1382.  
  1383.             res = acmStreamOpen(pfad->pp, pfad->hdrv, pfad->iFormat, pfad->oFormat, NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME);
  1384.             if (!res)
  1385.                 pfad->success = true;
  1386.             else {
  1387.                 res = acmStreamOpen(pfad->pp, pfad->hdrv, pfad->iFormat, pfad->oFormat, NULL, 0, 0, 0);
  1388.                 if (!res)
  1389.                     pfad->success = true;
  1390.                 else
  1391.                     acmDriverClose(pfad->hdrv, 0);
  1392.             }
  1393.         }
  1394.     }
  1395.  
  1396.     return !pfad->success;
  1397. }
  1398.  
  1399.  
  1400. AudioCompressor::AudioCompressor(AudioStream *src, WAVEFORMATEX *dst_format, long dst_format_len) : AudioStream() {
  1401.     WAVEFORMATEX *iFormat = src->GetFormat();
  1402.     WAVEFORMATEX *oFormat;
  1403.     DWORD dwOutputBufferSize;
  1404.     MMRESULT err;
  1405.  
  1406.     hADriver = NULL;
  1407.     hACStream = NULL;
  1408.     pwfexTempOutput = NULL;
  1409.     inputBuffer = outputBuffer = NULL;
  1410.     holdBuffer = NULL;
  1411.     holdBufferSize = 0;
  1412.     holdBufferOffset = 0;
  1413.  
  1414.     // Stupid Microsoft Audio Codec.
  1415.  
  1416.     oFormat = AllocFormat(dst_format_len);
  1417.     memcpy(oFormat, dst_format, dst_format_len);
  1418.  
  1419.     SetSource(src);
  1420.  
  1421.     memset(&ashBuffer, 0, sizeof ashBuffer);
  1422.  
  1423.     do {
  1424.         // Try opening with ACM_STREAMOPENF_NONREALTIME.
  1425.  
  1426.         if (!(err = acmStreamOpen(&hACStream, NULL, iFormat, oFormat, NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME)))
  1427.             break;
  1428.  
  1429.         // Still didn't work, try every f*cking driver.
  1430.  
  1431.         struct FrustratedACMOpenData fad;
  1432.  
  1433.         fad.pp        = &hACStream;
  1434.         fad.hdrv    = NULL;
  1435.         fad.iFormat = iFormat;
  1436.         fad.oFormat = oFormat;
  1437.         fad.success = false;
  1438.  
  1439.         if (!acmDriverEnum(ACMStreamOpenCallback, (DWORD)&fad, 0) && fad.success) {
  1440.             hADriver = fad.hdrv;
  1441.             break;
  1442.         }
  1443.  
  1444.         // Damn!
  1445.  
  1446.         if (err == ACMERR_NOTPOSSIBLE)
  1447.             throw MyError("Error initializing audio stream compression:\nThe requested conversion is not possible.");
  1448.         else
  1449.             throw MyError("Error initializing audio stream compression.");
  1450.  
  1451.     } while(false);
  1452.  
  1453.     if (acmStreamSize(hACStream, INPUT_BUFFER_SIZE, &dwOutputBufferSize, ACM_STREAMSIZEF_SOURCE))
  1454.         throw MyError("Error querying audio compression.");
  1455.  
  1456.     if (!(inputBuffer = allocmem(INPUT_BUFFER_SIZE))
  1457.         || !(outputBuffer = allocmem(dwOutputBufferSize)))
  1458.  
  1459.         throw MyMemoryError();
  1460.  
  1461.     ashBuffer.cbStruct        = sizeof(ACMSTREAMHEADER);
  1462.     ashBuffer.pbSrc            = (LPBYTE)inputBuffer;
  1463.     ashBuffer.cbSrcLength    = INPUT_BUFFER_SIZE;
  1464.     ashBuffer.pbDst            = (LPBYTE)outputBuffer;
  1465.     ashBuffer.cbDstLength    = dwOutputBufferSize;
  1466.  
  1467.     if (acmStreamPrepareHeader(hACStream, &ashBuffer, 0))
  1468.         throw MyError("Error preparing audio compression buffers.");
  1469.  
  1470.     ashBuffer.cbSrcLength = 0;
  1471.  
  1472.     bytesPerInputSample = iFormat->nBlockAlign;
  1473.     bytesPerOutputSample = oFormat->nBlockAlign;
  1474.  
  1475.     fStreamEnded = FALSE;
  1476. }
  1477.  
  1478. AudioCompressor::~AudioCompressor() {
  1479.     if (hACStream) {
  1480.         if (ashBuffer.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED) acmStreamUnprepareHeader(hACStream, &ashBuffer, 0);
  1481.         acmStreamClose(hACStream, 0);
  1482.     }
  1483.     if (hADriver)
  1484.         acmDriverClose(hADriver, 0);
  1485.  
  1486.     if (inputBuffer)    freemem(inputBuffer);
  1487.     if (outputBuffer)    freemem(outputBuffer);
  1488.     if (holdBuffer)        freemem(holdBuffer);
  1489.  
  1490.     delete[] pwfexTempOutput;
  1491. }
  1492.  
  1493. void AudioCompressor::CompensateForMP3() {
  1494.  
  1495.     // Fraunhofer-IIS's MP3 codec has a compression delay that we need to
  1496.     // compensate for.  Comparison of PCM input, F-IIS output, and
  1497.     // WinAmp's Nitrane output reveals that the decompressor half of the
  1498.     // ACM codec is fine, but the compressor inserts a delay of 1373
  1499.     // (0x571) samples at the start.  This is a lag of 2 frames at
  1500.     // 30fps and 22KHz, so it's significant enough to be noticed.  At
  1501.     // 11KHz, this becomes a tenth of a second.  Needless to say, the
  1502.     // F-IIS MP3 codec is a royal piece of sh*t.
  1503.     //
  1504.     // By coincidence, the MPEGLAYER3WAVEFORMAT struct has a field
  1505.     // called nCodecDelay which is set to this value...
  1506.  
  1507.     if (GetFormat()->wFormatTag == WAVE_FORMAT_MPEGLAYER3) {
  1508.         long lSamplesToRead = ((MPEGLAYER3WAVEFORMAT *)GetFormat())->nCodecDelay;
  1509.         long ltActualBytes, ltActualSamples;
  1510.         int nBlockAlign = source->GetFormat()->nBlockAlign;
  1511.  
  1512.         do {
  1513.             long tc;
  1514.  
  1515.             tc = lSamplesToRead;
  1516.             if (tc > INPUT_BUFFER_SIZE / nBlockAlign)
  1517.                 tc = INPUT_BUFFER_SIZE / nBlockAlign;
  1518.  
  1519.             ltActualSamples = source->Read((char *)inputBuffer, tc,
  1520.                         <ActualBytes);
  1521.  
  1522.             lSamplesToRead -= ltActualSamples;
  1523.         } while(lSamplesToRead>0 && ltActualBytes);
  1524.  
  1525.         if (!ltActualBytes || source->isEnd())
  1526.             fStreamEnded = TRUE;
  1527.     }
  1528. }
  1529.  
  1530. void AudioCompressor::ResizeHoldBuffer(long lNewSize) {
  1531.     void *holdBufferTemp;
  1532.  
  1533.     if (holdBufferSize >= lNewSize) return;
  1534.  
  1535.     if (!(holdBufferTemp = allocmem(holdBufferSize = ((lNewSize + 65535) & -65536))))
  1536.         throw MyError("AudioCompressor: Unable to resize hold buffer");
  1537.  
  1538.     memcpy(holdBufferTemp, holdBuffer, holdBufferOffset);
  1539.     freemem(holdBuffer);
  1540.  
  1541.     holdBuffer = holdBufferTemp;
  1542. }
  1543.  
  1544. void AudioCompressor::WriteToHoldBuffer(void *data, long lBytes) {
  1545.     if (lBytes + holdBufferOffset > holdBufferSize)
  1546.         ResizeHoldBuffer(lBytes + holdBufferOffset);
  1547.  
  1548.     memcpy((char *)holdBuffer + holdBufferOffset, data, lBytes);
  1549.     holdBufferOffset += lBytes;
  1550. }
  1551.  
  1552. void *AudioCompressor::Compress(long lInputSamples, long *lplSrcInputSamples, long *lplOutputBytes, long *lplOutputSamples) {
  1553.     LONG ltActualSamples, ltActualBytes;
  1554.     LONG lActualSrcSamples = 0;
  1555.  
  1556. //    _RPT1(0,"Compressor: we want to convert %ld input samples\n", lInputSamples);
  1557.  
  1558.     holdBufferOffset = 0;
  1559.  
  1560.     while(lInputSamples > 0 && !fStreamEnded) {
  1561.  
  1562.         // fill the input buffer up!
  1563.  
  1564.         if (ashBuffer.cbSrcLength < INPUT_BUFFER_SIZE) {
  1565.             LONG lBytes=0;
  1566.             long lSamplesToRead;
  1567.  
  1568.             do {
  1569.                 lSamplesToRead = min(lInputSamples, (INPUT_BUFFER_SIZE - ashBuffer.cbSrcLength)/bytesPerInputSample);
  1570.  
  1571.                 ltActualSamples = source->Read((char *)inputBuffer + ashBuffer.cbSrcLength, lSamplesToRead,
  1572.                             <ActualBytes);
  1573.  
  1574.                 ashBuffer.cbSrcLength += ltActualBytes;
  1575.  
  1576.                 lBytes += ltActualBytes;
  1577.  
  1578.                 lInputSamples -= ltActualSamples;
  1579.                 lActualSrcSamples += ltActualSamples;
  1580.  
  1581.                 _ASSERT(lInputSamples >= 0);
  1582.             } while(ashBuffer.cbSrcLength < INPUT_BUFFER_SIZE && lInputSamples>0 && ltActualBytes);
  1583.  
  1584.             if (!ltActualBytes || source->isEnd())
  1585.                 fStreamEnded = TRUE;
  1586.         }
  1587.  
  1588.         // ask ACM to convert for us
  1589.  
  1590.         ashBuffer.cbSrcLengthUsed = 0;
  1591.         ashBuffer.cbDstLengthUsed = 0;
  1592.  
  1593. //        _RPT2(0,"Converting %ld bytes to %ld\n", ashBuffer.cbSrcLength, ashBuffer.cbDstLength);
  1594.  
  1595.     VDCHECKPOINT;
  1596.         if (acmStreamConvert(hACStream, &ashBuffer, fStreamEnded ? ACM_STREAMCONVERTF_END : ACM_STREAMCONVERTF_BLOCKALIGN))
  1597.             throw MyError("Audio Compression Manager (ACM) failure on compress");
  1598.     VDCHECKPOINT;
  1599.  
  1600. //        _RPT2(0,"Converted %ld bytes to %ld\n", ashBuffer.cbSrcLengthUsed, ashBuffer.cbDstLengthUsed);
  1601.  
  1602.         // if ACM didn't use all the source data, copy the remainder down
  1603.  
  1604.         if (ashBuffer.cbSrcLengthUsed < ashBuffer.cbSrcLength) {
  1605.             long left = ashBuffer.cbSrcLength - ashBuffer.cbSrcLengthUsed;
  1606.  
  1607.             memmove(inputBuffer, (char *)inputBuffer + ashBuffer.cbSrcLengthUsed, left);
  1608.  
  1609.             ashBuffer.cbSrcLength = left;
  1610.         } else
  1611.             ashBuffer.cbSrcLength = 0;
  1612.  
  1613.         // chuck all pending data to the hold buffer
  1614.  
  1615.         WriteToHoldBuffer(outputBuffer, ashBuffer.cbDstLengthUsed);
  1616.     }
  1617.  
  1618.     *lplOutputBytes = holdBufferOffset;
  1619.     *lplOutputSamples = (holdBufferOffset + bytesPerOutputSample - 1) / bytesPerOutputSample;
  1620.     *lplSrcInputSamples = lActualSrcSamples;
  1621.  
  1622. //    _RPT2(0,"Compressor: %ld bytes, %ld samples\n", *lplOutputBytes, *lplOutputSamples);
  1623.  
  1624.     return holdBuffer;
  1625. }
  1626.  
  1627. BOOL AudioCompressor::isEnd() {
  1628.     return fStreamEnded;
  1629. }
  1630.  
  1631. ///////////////////////////////////////////////////////////////////////////
  1632. //
  1633. //    Corrects the nAvgBytesPerFrame for that stupid Fraunhofer-IIS
  1634. //    codec.
  1635.  
  1636.  
  1637. AudioL3Corrector::AudioL3Corrector() {
  1638.     samples = frame_bytes = 0;
  1639.     read_left = 4;
  1640.     header_mode = true;
  1641. }
  1642.  
  1643. long AudioL3Corrector::ComputeByterate(long sample_rate) {
  1644.     return MulDiv(frame_bytes, sample_rate, samples);
  1645. }
  1646.  
  1647. void AudioL3Corrector::Process(void *buffer, long bytes) {
  1648.     static const int bitrates[2][16]={
  1649.         {0, 8,16,24,32,40,48,56, 64, 80, 96,112,128,144,160,0},
  1650.         {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}
  1651.     };
  1652.     static const long samp_freq[4] = {44100, 48000, 32000, 0};
  1653.  
  1654.     int cnt=0;
  1655.     int tc;
  1656.  
  1657.     while(cnt < bytes) {
  1658.         tc = bytes - cnt;
  1659.         if (tc > read_left)
  1660.             tc = read_left;
  1661.  
  1662.         if (header_mode)
  1663.             memcpy(&hdr_buffer[4-read_left], buffer, tc);
  1664.  
  1665.         buffer = (char *)buffer + tc;
  1666.         cnt += tc;
  1667.         read_left -= tc;
  1668.  
  1669.         if (read_left <= 0)
  1670.             if (header_mode) {
  1671.                 // We've got a header!  Process it...
  1672.  
  1673.                 long hdr = *(long *)hdr_buffer;
  1674.                 long samp_rate, framelen;
  1675.  
  1676.                 if ((hdr & 0xE0FF) != 0xE0FF)
  1677.                     throw MyError("MPEG audio sync error: try disabling MPEG audio time correction");
  1678.  
  1679.                 samp_rate = samp_freq[(hdr>>18)&3];
  1680.  
  1681.                 if (!((hdr>>11)&1)) {
  1682.                     samp_rate /= 2;
  1683.                     samples += 576;
  1684.                 } else
  1685.                     samples += 1152;
  1686.  
  1687.                 if (!(hdr & 0x1000))
  1688.                     samp_rate /= 2;
  1689.  
  1690.                 framelen = (bitrates[(hdr>>11)&1][(hdr>>20)&15] * (((hdr>>11)&1) ? 144000 : 72000)) / samp_rate;
  1691.  
  1692.                 if (hdr&0x20000) ++framelen;
  1693.  
  1694.                 // update statistics
  1695.  
  1696.                 frame_bytes += framelen;
  1697.  
  1698.                 // start skipping the remainder
  1699.  
  1700.                 read_left = framelen - 4;
  1701.                 header_mode = false;
  1702.  
  1703.             } else {
  1704.  
  1705.                 // Done skipping frame data; collect the next header
  1706.  
  1707.                 read_left = 4;
  1708.                 header_mode = true;
  1709.             }
  1710.     }
  1711. }
  1712.  
  1713. ///////////////////////////////////////////////////////////////////////////
  1714.  
  1715. long AudioTranslateVideoSubset(FrameSubset& dst, FrameSubset& src, long usPerFrame, WAVEFORMATEX *pwfex) {
  1716.     FrameSubsetNode *fsn = src.getFirstFrame();
  1717.     const __int64 i64usPerFrame = usPerFrame;
  1718.     const long lSampPerSec = pwfex->nSamplesPerSec;
  1719.     const long nBytesPerSec = pwfex->nAvgBytesPerSec;
  1720.     const int nBlockAlign = pwfex->nBlockAlign;
  1721.     long total = 0;
  1722.  
  1723.     // I like accuracy, so let's strive for accuracy.  Accumulate errors as we go;
  1724.     // use them to offset the starting points of subsequent segments, never being
  1725.     // more than 1/2 segment off.
  1726.     //
  1727.     // The conversion equation is in units of (1000000*nBlockAlign).
  1728.  
  1729.     __int64 nError = 0;
  1730.     __int64 nMultiplier = i64usPerFrame * nBytesPerSec;
  1731.     __int64 nDivisor = 1000000i64*nBlockAlign;
  1732.     __int64 nRound = nDivisor/2;
  1733.     long nTotalFramesAccumulated = 0;
  1734.  
  1735.     while(fsn) {
  1736.         long start, end;
  1737.  
  1738.         // Compute error.
  1739.         //
  1740.         // Ideally, we want the audio and video streams to be of the exact length.
  1741.         //
  1742.         // Audiolen = (videolen * usPerFrame * nBytesPerSec) / (1000000*nBlockAlign);
  1743.  
  1744.         nError = total*nDivisor - (nTotalFramesAccumulated * nMultiplier);
  1745.  
  1746. _RPT1(0,"nError = %I64d\n", nError);
  1747.  
  1748.         // Add a block.
  1749.  
  1750.         start = ((__int64)fsn->start * nMultiplier + nRound + nError) / nDivisor;
  1751.         end = ((__int64)(fsn->start + fsn->len) * nMultiplier + nRound) / nDivisor;
  1752.  
  1753.         nTotalFramesAccumulated += fsn->len;
  1754.  
  1755.         dst.addRange(start, end-start);
  1756.  
  1757.         total += end-start;
  1758.  
  1759.         fsn = src.getNextFrame(fsn);
  1760.     }
  1761.  
  1762.     return total;
  1763. }
  1764.  
  1765. AudioSubset::AudioSubset(AudioStream *src, FrameSubset *pfs, long usPerFrame, long preskew) : AudioStream() {
  1766.     memcpy(AllocFormat(src->GetFormatLen()), src->GetFormat(), src->GetFormatLen());
  1767.  
  1768.     SetSource(src);
  1769.  
  1770. #if 1
  1771.  
  1772.     long total = AudioTranslateVideoSubset(subset, *pfs, usPerFrame, src->GetFormat());
  1773.  
  1774. #else
  1775.     while(fsn) {
  1776.         long start, end;
  1777.  
  1778. //        start = ((__int64)fsn->start * i64usPerFrame * lSampPerSec) / 1000000;
  1779. //        end = ((__int64)(fsn->start + fsn->len) * i64usPerFrame * lSampPerSec) / 1000000;
  1780.  
  1781.         start = ((__int64)fsn->start * i64usPerFrame * nBytesPerSec + 500000*nBlockAlign) / (1000000*nBlockAlign);
  1782.         end = ((__int64)(fsn->start + fsn->len) * i64usPerFrame * nBytesPerSec + 500000*nBlockAlign) / (1000000*nBlockAlign);
  1783.  
  1784.         subset.addRange(start, end-start);
  1785.  
  1786.         total += end-start;
  1787.  
  1788.         fsn = pfs->getNextFrame(fsn);
  1789.     }
  1790. #endif
  1791.  
  1792.     subset.deleteRange(0, MulDiv(preskew, src->GetFormat()->nSamplesPerSec, 1000));
  1793.  
  1794.     stream_len = total;
  1795.  
  1796.     SetLimit(total);
  1797.  
  1798.     pfsnCur = subset.getFirstFrame();
  1799.     iOffset = 0;
  1800.     lSrcPos = 0;
  1801.     lSkipSize = sizeof skipBuffer / src->GetFormat()->nBlockAlign;
  1802. }
  1803.  
  1804. AudioSubset::~AudioSubset() {
  1805. }
  1806.  
  1807. long AudioSubset::_Read(void *buffer, long samples, long *lplBytes) {
  1808.     int offset, actual;
  1809.  
  1810.     if (!pfsnCur) {
  1811.         *lplBytes = 0;
  1812.         return 0;
  1813.     }
  1814.  
  1815.     while ((offset = pfsnCur->start - lSrcPos) > 0) {
  1816.         long t;
  1817.  
  1818.         if (source->Skip(offset)) {
  1819.             lSrcPos += offset;
  1820.             break;
  1821.         }
  1822.  
  1823.         if (offset > lSkipSize) offset = lSkipSize;
  1824.  
  1825.         actual = source->Read(skipBuffer, offset, &t);
  1826.  
  1827.         if (!actual) {
  1828.             *lplBytes = 0;
  1829.             return 0;
  1830.         }
  1831.  
  1832.         lSrcPos += actual;
  1833.     }
  1834.  
  1835.     if (samples > pfsnCur->len - iOffset)
  1836.         samples = pfsnCur->len - iOffset;
  1837.  
  1838.     samples = source->Read(buffer, samples, lplBytes);
  1839.  
  1840.     iOffset += samples;
  1841.     lSrcPos += samples;
  1842.     while (pfsnCur && iOffset >= pfsnCur->len) {
  1843.         iOffset -= pfsnCur->len;
  1844.         pfsnCur = subset.getNextFrame(pfsnCur);
  1845.     }
  1846.  
  1847.     return samples;
  1848. }
  1849.  
  1850. BOOL AudioSubset::_isEnd() {
  1851.     return !pfsnCur || source->isEnd();
  1852. }
  1853.  
  1854. ///////////////////////////////////////////////////////////////////////////
  1855. //
  1856. //    AudioAmplifier
  1857. //
  1858. ///////////////////////////////////////////////////////////////////////////
  1859.  
  1860. static void amplify8(unsigned char *dst, int count, long lFactor) {
  1861.     long lBias = 0x8080 - 0x80*lFactor;
  1862.  
  1863.     if (count)
  1864.         do {
  1865.             int y = ((long)*dst++ * lFactor + lBias) >> 8;
  1866.  
  1867.             if (y<0) y=0; else if (y>255) y=255;
  1868.  
  1869.             dst[-1] = (unsigned char)y;
  1870.         } while(--count);
  1871. }
  1872.  
  1873. static void amplify16(signed short *dst, int count, long lFactor) {
  1874.     if (count)
  1875.         do {
  1876.             int y = ((long)*dst++ * lFactor + 0x80) >> 8;
  1877.  
  1878.             if (y<-0x7FFF) y=-0x7FFF; else if (y>0x7FFF) y=0x7FFF;
  1879.  
  1880.             dst[-1] = (signed short)y;
  1881.         } while(--count);
  1882. }
  1883.  
  1884. AudioStreamAmplifier::AudioStreamAmplifier(AudioStream *src, long _lFactor)
  1885. : lFactor(_lFactor) {
  1886.  
  1887.     WAVEFORMATEX *iFormat = src->GetFormat();
  1888.     WAVEFORMATEX *oFormat;
  1889.  
  1890.     memcpy(oFormat = AllocFormat(src->GetFormatLen()), iFormat, src->GetFormatLen());
  1891.  
  1892.     SetSource(src);
  1893. }
  1894.  
  1895. AudioStreamAmplifier::~AudioStreamAmplifier() {
  1896. }
  1897.  
  1898. long AudioStreamAmplifier::_Read(void *buffer, long samples, long *lplBytes) {
  1899.     long lActualSamples=0;
  1900.     long lBytes;
  1901.  
  1902.     lActualSamples = source->Read(buffer, samples, &lBytes);
  1903.  
  1904.     if (lActualSamples) {
  1905.         if (GetFormat()->wBitsPerSample > 8)
  1906.             amplify16((signed short *)buffer, lBytes/2, lFactor);
  1907.         else
  1908.             amplify8((unsigned char *)buffer, lBytes, lFactor);
  1909.     }
  1910.  
  1911.     if (lplBytes)
  1912.         *lplBytes = lBytes;
  1913.  
  1914.     return lActualSamples;
  1915. }
  1916.  
  1917. BOOL AudioStreamAmplifier::_isEnd() {
  1918.     return source->isEnd();
  1919. }
  1920.